<template>
  <div class="formatted-content">
    <div 
      class="markdown-content" 
      ref="markdownContainer"
      v-html="compiledMarkdown"
    ></div>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Watch } from 'vue-property-decorator';
import MarkdownIt from 'markdown-it';

@Component
export default class FormattedContent extends Vue {
  @Prop({ required: true }) content!: string;
  
  private md: MarkdownIt = new MarkdownIt({
    html: true,
    linkify: true,
    typographer: true
  });
  
  private compiledMarkdown: any = '';
  private htmlPreviews: Array<{
    id: string;
    code: string;
    element: HTMLElement | null;
  }> = [];

  mounted() {
    this.processContent();
    this.$nextTick(() => {
      this.attachPreviews();
    });
  }

  @Watch('content')
  onContentChanged() {
    this.processContent();
    this.$nextTick(() => {
      this.attachPreviews();
    });
  }

  private processContent() {
    this.compiledMarkdown = this.md.render(this.content);
    this.htmlPreviews = [];
  }

  private attachPreviews() {
    const container = this.$refs.markdownContainer as HTMLElement;
    if (!container) return;
    
    const codeBlocks = container.querySelectorAll('pre code.language-html');
    this.htmlPreviews = [];
    
    codeBlocks.forEach((codeBlock, index) => {
      const id = `preview-${Date.now()}-${index}`;
      const code = codeBlock.textContent || '';
      
      const previewContainer = document.createElement('div');
      previewContainer.className = 'html-preview-container';
      previewContainer.id = id;
      
      const preElement = codeBlock.closest('pre');
      if (preElement && preElement.parentNode) {
        preElement.parentNode.replaceChild(previewContainer, preElement);
      }
      
      this.renderPreview(id, code);
      
      this.htmlPreviews.push({
        id,
        code,
        element: previewContainer
      });
    });
  }

  private renderPreview(id: string, code: string) {
    const container = document.getElementById(id);
    if (!container) return;
    
    container.innerHTML = `
      <div class="preview-header">
        <div class="header-left">
          <span class="lang-tag">
            <i class="fab fa-html5"></i> HTML
          </span>
          <div class="preview-actions">
            <button class="action-btn copy-btn" data-id="${id}">
              <i class="fas fa-copy"></i>
              <span>复制代码</span>
            </button>
            <button class="action-btn refresh-btn" data-id="${id}">
              <i class="fas fa-sync-alt"></i>
              <span>刷新预览</span>
            </button>
          </div>
        </div>
        <div class="header-right">
          <div class="action-hint">实时预览</div>
        </div>
      </div>
      <div class="preview-content">
        <iframe 
          srcdoc="${this.escapeHtml(code)}"
          sandbox="allow-scripts allow-forms allow-same-origin"
          class="preview-iframe"
        ></iframe>
      </div>
    `;
    
    const copyBtn = container.querySelector(`.copy-btn[data-id="${id}"]`);
    const refreshBtn = container.querySelector(`.refresh-btn[data-id="${id}"]`);
    
    if (copyBtn) {
      copyBtn.addEventListener('click', () => {
        navigator.clipboard.writeText(code);
        this.showActionFeedback(copyBtn, '已复制!');
      });
    }
    
    if (refreshBtn) {
      refreshBtn.addEventListener('click', () => {
        this.renderPreview(id, code);
        this.showActionFeedback(refreshBtn, '已刷新!');
      });
    }
  }

  private showActionFeedback(button: Element, message: string) {
    const originalHtml = button.innerHTML;
    const feedback = document.createElement('div');
    feedback.className = 'action-feedback';
    feedback.textContent = message;
    
    button.innerHTML = '';
    button.appendChild(feedback);
    
    setTimeout(() => {
      button.innerHTML = originalHtml;
    }, 1500);
  }

  private escapeHtml(unsafe: string): string {
    return unsafe
      .replace(/&/g, "&amp;")
      .replace(/</g, "&lt;")
      .replace(/>/g, "&gt;")
      .replace(/"/g, "&quot;")
      .replace(/'/g, "&#039;");
  }
}
</script>

<style scoped lang="scss">
.formatted-content{
  max-width: 1200px;
  margin: 0 auto;
  padding: 0px;
  
  .markdown-content {
    .markdown-body {
      p, li, h1, h2, h3, h4, h5, h6 {
        white-space: normal;
      }
      
      h1, h2, h3, h4, h5, h6 {
        margin-top: 1.2em;
        margin-bottom: 0.6em;
        line-height: 1.3;
        padding-bottom: 0.3em;
        border-bottom: 1px solid #eaecef;
      }
      
      h1 { font-size: 1.8em; }
      h2 { font-size: 1.5em; }
      h3 { font-size: 1.3em; }
      h4 { font-size: 1.1em; }
      h5 { font-size: 1em; }
      h6 { font-size: 0.9em; color: #6a737d; }
    }
  }
}

 ::v-deep .html-preview-container {
      margin: 1px 0;
      border-radius: 4px;
      overflow: hidden;
      box-shadow: 0 12px 30px rgba(0, 0, 0, 0.25);
      background: linear-gradient(135deg, #1e293b, #0f172a);
      border: 1px solid rgba(94, 234, 212, 0.15);
      
      .preview-header {
        display: flex;
        justify-content: space-between;
        align-items: center;
        padding: 2px;
        height: 30px;
        background: linear-gradient(90deg, #1a202c, #2d3748);
        border-bottom: 1px solid rgba(255, 255, 255, 0.08);
        
        .header-left {
          display: flex;
          align-items: center;
          gap: 15px;
        }
        
        .header-right {
          height: 30px;

          .action-hint {
            background: rgba(94, 234, 212, 0.1);
            color: #5eead4;
            padding: 4px 12px;
            border-radius: 12px;
            font-size: 0.85rem;
            font-weight: 500;
            border: 1px solid rgba(94, 234, 212, 0.2);
          }
        }
        
       .lang-tag {
          display: flex;
          align-items: center;
          gap: 2px;
          background: rgba(94, 234, 212, 0.15);
          color: #5eead4;
          padding: 1px;
          
          border-radius: 4px;
          font-family: 'Roboto Mono', monospace;
          font-size: 12px;
          font-weight: 500;
          height: 30px;
          i {
            font-size: 12px;
          }
        }
        
        .preview-actions {
          display: flex;
          gap: 10px;
        }
      }
      
      .preview-content {
        padding: 2px;
        background: #0f172a;
        
        .preview-iframe {
          width: 100%;
          height: 100%;
          border: none;
          background: white;
          display: block;
          border-radius: 0 0 10px 10px;
        }
      }
    }

::v-deep .action-btn {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 5px;
  border-radius: 4px;
  font-family: 'Inter', sans-serif;
  font-weight: 500;
  font-size: 0.9rem;
  cursor: pointer;
  transition: all 0.3s ease;
  border: none;
  outline: none;
  position: relative;
  overflow: hidden;
  
  i {
    transition: transform 0.3s ease;
  }
  
  span {
    position: relative;
    z-index: 2;
  }
  
  &::before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: rgba(255, 255, 255, 0.1);
    z-index: 1;
    transition: opacity 0.3s ease;
    opacity: 0;
  }
  
  &:hover {
    transform: translateY(-2px);
    box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
    
    &::before {
      opacity: 1;
    }
    
    i {
      transform: scale(1.1);
    }
  }
  
  &:active {
    transform: translateY(1px);
  }
  
  &.copy-btn {
    background: linear-gradient(135deg, rgba(96, 165, 250, 0.9), rgba(59, 130, 246, 0.9));
    color: white;
    
    &:hover {
      background: linear-gradient(135deg, rgba(96, 165, 250, 1), rgba(59, 130, 246, 1));
      box-shadow: 0 4px 15px rgba(96, 165, 250, 0.4);
    }
  }
  
  &.refresh-btn {
    background: linear-gradient(135deg, rgba(94, 234, 212, 0.9), rgba(56, 189, 248, 0.9));
    color: white;
    
    &:hover {
      background: linear-gradient(135deg, rgba(94, 234, 212, 1), rgba(56, 189, 248, 1));
      box-shadow: 0 4px 15px rgba(94, 234, 212, 0.4);
    }
  }
}

.action-feedback {
  animation: fadeInOut 1.5s ease;
  font-weight: 600;
}

@keyframes fadeInOut {
  0% { opacity: 0; transform: translateY(5px); }
  20% { opacity: 1; transform: translateY(0); }
  80% { opacity: 1; transform: translateY(0); }
  100% { opacity: 0; transform: translateY(-5px); }
}
</style>